package com.poetry.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.poetry.domain.dto.QuizDTO;
import com.poetry.domain.dto.TranslationDTO;
import com.poetry.domain.po.Poem;
import com.poetry.domain.po.Quiz;
import com.poetry.domain.po.QuizList;
import com.poetry.exception.R;
import com.poetry.mapper.QuizMapper;
import com.poetry.service.IPoemService;
import com.poetry.service.IQuizListService;
import com.poetry.service.IQuizService;
import com.poetry.util.UserContext;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class QuizServiceImpl extends ServiceImpl<QuizMapper, Quiz>
        implements IQuizService {
    private static final Set<Character> PUNCTUATION = new HashSet<>(Arrays.asList(
            '\n', '，', '。', '！', '？', '；', '：', '、', '「', '」', '『', '』', '《', '》', '（', '）', '—'
    ));
    private static final String[] keywords = {"月", "山", "水", "花", "酒", "云", "风", "雨", "与", "然", "之", "知", "亦"};
    @Resource
    private IPoemService poemService;
    @Resource
    private IQuizListService quizListService;
    @Resource
    @Qualifier("chatClientNoMemory")
    private ChatClient chatClientNoMemory;

    @Transactional
    @Override
    public R<QuizDTO> generateQuiz(Integer poemId, Integer difficulty) {
        Integer userId = UserContext.getUserId();
        if (userId == null) {
            return R.error("用户未登录");
        }
        // 获取诗词内容
        Poem poem = poemService.getById(poemId);
        String content = poem.getContent();

        List<String> validSegments = extractValidSegments(content);

        if (validSegments.isEmpty()) {
            throw new IllegalArgumentException("文本中没有有效的非标点片段");
        }

        // 根据难度生成答案
        Random random = new Random();
        TreeMap<Integer, String> treeMap = new TreeMap<>();
        String question = content;
        for (String segment : validSegments) {
            int cnt = (segment.length() * difficulty) / 100;
            int start = content.indexOf(segment);
            for (int i = 0; i < cnt; i++) {
                int index = random.nextInt(segment.length());
                if (treeMap.containsKey(index + start)) {
                    i--;
                } else {
                    System.out.println(segment.charAt(index) + "");
                    treeMap.put(index + start, segment.charAt(index) + "");
                }
            }
        }

        for (int i = 0; i < content.length(); i++) {
            if (treeMap.containsKey(i)) {
                question = question.substring(0, i) + "_" + question.substring(i + 1);
            }
        }
        List<String> answers = new ArrayList<>();
        treeMap.forEach((Integer key, String value) -> answers.add(value));
        List<String> options = generateOptions(answers, answers.getFirst());

        // 保存题目
        Quiz quiz = new Quiz();
        quiz.setUserId(UserContext.getUserId());
        quiz.setPoemId(poemId);
        quiz.setQuestion(question);
        quiz.setAnswers(String.join(",", answers));
        Quiz tmp = this.query().eq("user_id", userId).one();
        if (tmp != null) {
            quiz.setId(tmp.getId());
        }
        boolean isSuccess = this.saveOrUpdate(quiz);
        if (!isSuccess) {
            return R.error("题目生成失败");
        }

        quiz = this.query().eq("user_id", UserContext.getUserId()).one();
        QuizDTO dto = new QuizDTO();
        dto.setId(quiz.getId());
        dto.setQuestion(quiz.getQuestion());
        dto.setOptions(options);

        QuizList quizList = quizListService.query()
                .eq("user_id", userId).eq("poem_id", poemId).one();
        if (quizList != null) {
            quizList.setUpdateTime(LocalDateTime.now());
            if (!quizList.getStatus() && difficulty == 100) {
                quizList.setStatus(true);
            }
            quizListService.updateById(quizList);
        }
        return R.success("题目生成成功", dto);
    }

    // 提取不含标点的有效片段
    private List<String> extractValidSegments(String text) {
        List<String> segments = new ArrayList<>();
        StringBuilder currentSegment = new StringBuilder();

        for (char c : text.toCharArray()) {
            if (PUNCTUATION.contains(c)) {
                if (!currentSegment.isEmpty()) {
                    segments.add(currentSegment.toString());
                    currentSegment = new StringBuilder();
                }
            } else {
                currentSegment.append(c);
            }
        }

        // 添加最后一个片段
        if (!currentSegment.isEmpty()) {
            segments.add(currentSegment.toString());
        }

        // 过滤长度2-5个字符的片段
        return segments.stream()
                .filter(s -> !(s.length() <= 3))
                .collect(Collectors.toList());
    }

    private List<String> generateOptions(List<String> answers, String target) {
        List<String> options = new ArrayList<>();
        options.add(target);
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int index1 = random.nextInt(answers.size());
            if (options.contains(answers.get(index1))) {
                index1 = random.nextInt(keywords.length);
                while (options.contains(keywords[index1])) {
                    index1 = random.nextInt(keywords.length);
                }
                options.add(keywords[index1]);

            } else {
                options.add(answers.get(index1));
            }
        }
        Collections.shuffle(options);
        return options;
    }

    @Override
    @Transactional
    public R<QuizDTO> checkAnswer(Integer quizId, String answer) {
        Quiz quiz = getById(quizId);
        String content = poemService.getById(quiz.getPoemId()).getContent();
        String question = quiz.getQuestion();
        int index = question.indexOf("_");
        if (content.charAt(index) != answer.charAt(0)) {
            return R.error("回答错误");
        }
        question = question.substring(0, index) + (content.charAt(index) + "") + question.substring(index + 1);
        int target = question.indexOf("_");
        if (target == -1) {
            QuizDTO dto = new QuizDTO();
            dto.setId(quizId);
            dto.setQuestion(content);
            return R.success("背诵完成", dto);
        }
        List<String> options = generateOptions(Arrays.stream(quiz.getAnswers().split(",")).toList(),
                content.charAt(target) + "");
        QuizDTO quizDTO = new QuizDTO();
        quizDTO.setId(quizId);
        quizDTO.setQuestion(question);
        quizDTO.setOptions(options);
        quiz.setQuestion(question);
        boolean isSuccess = this.updateById(quiz);
        if (!isSuccess) {
            return R.error("数据库错误");
        }
        return R.success("回答正确", quizDTO);
    }

    public R<QuizDTO> generateTranslation(Integer poemId) {
        Integer userId = UserContext.getUserId();
        if (userId == null) {
            return R.error("用户未登录");
        }
        Poem poem = poemService.getById(poemId);
        String content = poem.getContent();
        Random random = new Random();
        List<String> validSegments = Arrays.stream(content.split("\n")).toList();

        if (validSegments.isEmpty()) {
            throw new IllegalArgumentException("文本中没有有效的非标点片段");
        }
        List<String> candidates = validSegments.stream()
                .filter(s -> s.length() >= 6)
                .toList();
        if (candidates.isEmpty()) {
            candidates = validSegments;
        }
        String segments = candidates.get(random.nextInt(candidates.size()));
        // 保存题目
        Quiz quiz = new Quiz();
        quiz.setUserId(UserContext.getUserId());
        quiz.setPoemId(poemId);
        quiz.setQuestion(segments);
        Quiz tmp = this.query().eq("user_id", userId).one();
        if (tmp != null) {
            quiz.setId(tmp.getId());
        }
        boolean isSuccess = this.saveOrUpdate(quiz);
        if (!isSuccess) {
            return R.error("题目生成失败");
        }

        quiz = this.query().eq("user_id", UserContext.getUserId()).one();
        QuizDTO dto = new QuizDTO();
        dto.setId(quiz.getId());
        dto.setQuestion(quiz.getQuestion());

        QuizList quizList = quizListService.query()
                .eq("user_id", userId).eq("poem_id", poemId).one();
        if (quizList != null) {
            quizList.setUpdateTime(LocalDateTime.now());
            quizListService.updateById(quizList);
        }
        return R.success("翻译练习生成成功", dto);
    }

    public R<TranslationDTO> evaluateTranslation(Integer quizId, String userTranslation){
        Quiz quiz = getById(quizId);
        String content = quiz.getQuestion();
        String prompt = String.format("""
            你是一位精通中国古典文学的专家，请根据以下评分标准对用户的古文翻译进行评分：
            
            ### 评分标准：
            1. 准确性（40分）：是否准确传达了原文的意思
            2. 流畅性（30分）：翻译是否通顺自然，符合现代汉语表达习惯
            3. 完整性（20分）：是否完整表达了原文的所有要素
            4. 文学性（10分）：是否保持了原文的文学美感
            
            ### 评分格式要求：
            请返回一个严格的JSON对象，包含以下字段：
            {
                "accuracyScore": 准确性得分(0-40),
                "fluencyScore": 流畅性得分(0-30),
                "completenessScore": 完整性得分(0-20),
                "literarinessScore": 文学性得分(0-10),
                "overallScore": 总分(0-100),
                "strengths": "翻译的优点（50字以内）",
                "weaknesses": "翻译的不足（50字以内）",
                "suggestions": "改进建议（50字以内）"
            }
            
            ### 原文：
            %s
            
            ### 用户翻译：
            %s
            """, content, userTranslation);
        String modelResponse = chatClientNoMemory.prompt()
                .system(prompt)
                .user(userTranslation)
                .advisors(a -> a.param("chat_memory_enabled", false))
                .call()
                .content();
        if (modelResponse == null) {
            return R.error("AI评判失败");
        }
        Pattern pattern = Pattern.compile("\\{.*}", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(modelResponse);
        String jsonPart = matcher.find()? matcher.group(): modelResponse;
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return R.success("AI评判成功", objectMapper.readValue(jsonPart, TranslationDTO.class));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}
